#include "control.h"
#include "ui_control.h"
#include "includes.h"

control::control(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::control)
{
    ui->setupUi(this);

    ui->Debug_Ctrl->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏滚动条

    /* 单选框添加到一个组 */
    pbuttonGroup = new QButtonGroup(this);
    pbuttonGroup->addButton(ui->radio_CtrlData1,0);
    pbuttonGroup->addButton(ui->radio_CtrlData2,1);
    pbuttonGroup->addButton(ui->radio_CtrlData3,2);

    connect(ui->radio_CtrlData1, SIGNAL(clicked()), this, SLOT(onRadioClickSlot()));
    connect(ui->radio_CtrlData2, SIGNAL(clicked()), this, SLOT(onRadioClickSlot()));
    connect(ui->radio_CtrlData3, SIGNAL(clicked()), this, SLOT(onRadioClickSlot()));

    /* 限制输入框 */
    QDoubleValidator * qFloat = new QDoubleValidator(-72000,72000,2,this);
    ui->data_ctrl1->setValidator(qFloat);
    ui->data_ctrl2->setValidator(qFloat);
    ui->data_ctrl3->setValidator(qFloat);

    //初始化单选框
    this->MotorDataNum = 1;

    // 抗锯齿
    ui->Charts_Angle->setRenderHint(QPainter::RenderHint::Antialiasing);

    this->CreateChart();

    //设置快捷键
    ui->Bt_CtrlBack->setShortcut(QKeySequence("Up"));
    ui->Bt_CtrlStraight->setShortcut(Qt::Key_Enter);
    ui->Bt_Ctrl0->setShortcut(QKeySequence("Down"));

    qApp->installEventFilter(this);//整个窗口都加上事件过滤
    qDebug()<<this->WaveFormMax;
}

/* 重写回车事件，绑定回车发送 */
void control::keyPressEvent(QKeyEvent *event)
{
    if(Qt::Key_Return == event->key())
    {
        this->on_Bt_CtrlStraight_clicked();
    }
}

void control::CreateChart(void)
{
    chart_angle   = new QChart();
    chart_speed   = new QChart();
    chart_current = new QChart();

    Angleaxis_y = new QValueAxis();
    Speedaxis_y = new QValueAxis();
    Iqaxis_y = new QValueAxis();

    //不显示具体的文字
    chart_angle->legend()->hide();
    chart_speed->legend()->hide();
    chart_current->legend()->hide();

    chart_angle->setTitle("角度");
    chart_speed->setTitle("速度");
    chart_current->setTitle("电流");

    // 创建线性数据列（QSplineSeries表示这是一条曲线）
    lsAngle = new QLineSeries();
    lsSpeed = new QLineSeries();
    lsIq = new QLineSeries();

    lsSetAngle = new QLineSeries();
    lsSetSpeed = new QLineSeries();
    lsSetIq = new QLineSeries();

//    lsAngle
    lsSetAngle->setColor("#D32F2F");
    lsSetSpeed->setColor("#D32F2F");
    lsSetIq->setColor("#D32F2F");

    chart_angle->addSeries(lsAngle);
    chart_angle->addSeries(lsSetAngle);
    chart_speed->addSeries(lsSpeed);
    chart_current->addSeries(lsIq);

    Angleaxis_y->setRange(-0,0);
    Speedaxis_y->setRange(-0,0);
    Iqaxis_y->setRange(-0,0);

    chart_angle->addAxis(Angleaxis_y, Qt::AlignLeft);
    chart_speed->addAxis(Speedaxis_y, Qt::AlignLeft);
    chart_current->addAxis(Iqaxis_y, Qt::AlignLeft);
    lsAngle->attachAxis(Angleaxis_y);
    lsSetAngle->attachAxis(Angleaxis_y);
    lsSpeed->attachAxis(Speedaxis_y);
    lsIq->attachAxis(Iqaxis_y);

    ui->Charts_Angle->setChart(chart_angle);
    ui->Charts_Speed->setChart(chart_speed);
    ui->Charts_Current->setChart(chart_current);

    //显示最大容量
    this->WaveFormMax = ui->input_DataMax->text().toInt();
}

//事件过滤器
bool control::eventFilter(QObject *obj, QEvent *e)
{
    if (obj == this->ui->data_ctrl1 && e->type() == QEvent::MouseButtonPress) {
        this->ui->radio_CtrlData1->setChecked(1);
        this->onRadioClickSlot();
    }
    if (obj == this->ui->data_ctrl2 && e->type() == QEvent::MouseButtonPress) {
        this->ui->radio_CtrlData2->setChecked(1);
        this->onRadioClickSlot();
    }
    if (obj == this->ui->data_ctrl3 && e->type() == QEvent::MouseButtonPress) {
        this->ui->radio_CtrlData3->setChecked(1);
        this->onRadioClickSlot();
    }

    return QObject::eventFilter(obj, e);
}

void control::showObjAdd(QChart *ChaObj, QLineSeries *LinObj, double data, QValueAxis *qva, uint64_t &x, double max, double min)
{
    ChaObj->removeSeries(LinObj);
    LinObj->append(x, data);
    if ( LinObj->count() > this->WaveFormMax ) {
        LinObj->removePoints(0, LinObj->count() - this->WaveFormMax);
    }
    // 给图表对象添加数据列
    ChaObj->addSeries(LinObj);

    double maxY=max, minY=min;

    for (int i=0; i < (int(x+1) < this->WaveFormMax ? int(x+1) : this->WaveFormMax); i++) {
        double y = LinObj->points()[i].y();
        maxY = maxY > y ? maxY :y;
        minY = minY < y ? minY :y;
    }

    qva->setRange(minY, maxY);
}

void control::showObjAdd(QChart *ChaObj, QLineSeries *LinObj, double data, QValueAxis *qva, uint64_t &x)
{
    this->showObjAdd(ChaObj, LinObj, data, qva, x, data, data);
}

void control::showAngleAdd(double data)
{
    static uint64_t x = 0;

    this->showObjAdd(chart_angle, lsAngle, data, this->Angleaxis_y, x);
    //this->showObjAdd(chart_angle, lsSetAngle, this->setAngle, this->Angleaxis_y, x, this->Angleaxis_y->max(), this->Angleaxis_y->min());

    x++;
}

void control::showSpeedAdd(double data)
{
    static uint64_t x = 0;

    this->showObjAdd(chart_speed, lsSpeed, data, this->Speedaxis_y, x);
    //this->showObjAdd(chart_speed, lsSetSpeed, this->setSpeed, this->Speedaxis_y, x, this->Speedaxis_y->max(), this->Speedaxis_y->min());

    x++;
}

void control::showIqdAdd(double data)
{
    static uint64_t x = 0;

    this->showObjAdd(chart_current, lsIq, data, this->Iqaxis_y, x);
    //this->showObjAdd(chart_current, lsSetIq, this->setSpeed, this->Iqaxis_y, x, this->Iqaxis_y->max(), this->Iqaxis_y->min());
    x++;
}

void control::set_wh(int w, int h)
{
    ui->horizontalLayoutWidget->setGeometry(0, 0, w, h);
}



control::~control()
{
    delete ui;
}

void control::CtrDebug(QString color, QString text)
{
    QTime time = QTime::currentTime();
    QString EndStr;
    EndStr.append("<font size=\" 2\";>[");
    EndStr.append(time.toString());
    EndStr.append("] : </font><font size=\" 2\"; color =\"");
    EndStr.append(color);
    EndStr.append("\">");
    EndStr.append(text);
    EndStr.append("</font>");

    ui->Debug_Ctrl->setFontPointSize(2);
    ui->Debug_Ctrl->append(EndStr);
    ui->Debug_Ctrl->moveCursor(QTextCursor::End);
}

void control::CtrDebug(QString color1, QString text1, QString color2, QString text2)
{
    QTime time = QTime::currentTime();
    QString EndStr;
    EndStr.append("<font size=\" 2\";>[");
    EndStr.append(time.toString());
    EndStr.append("] : </font><font size=\"2\"; color =\"");
    EndStr.append(color1);
    EndStr.append("\">");
    EndStr.append(text1);
    EndStr.append("</font>");
    EndStr.append(" <font size=\" 2\"; color =\"");
    EndStr.append(color2);
    EndStr.append("\">");
    EndStr.append(text2);
    EndStr.append("</font>");

    ui->Debug_Ctrl->append(EndStr);
    ui->Debug_Ctrl->moveCursor(QTextCursor::End);

}

uint8_t control::GetCtrlData(float &_txData)
{
    /* 根据选择的按钮选择对应的数据 */
    switch (this->MotorDataNum) {
        case 1:
            _txData = ui->data_ctrl1->text().toFloat();
            break;
        case 2:
            _txData = ui->data_ctrl2->text().toFloat();
            break;
        case 3:
            _txData = ui->data_ctrl3->text().toFloat();
            break;
        default:
            this->CtrDebug("#B71C1C", "未知的选项框，请选择你的哪组数据");
            return 0;
    }

    return  1;
}

void control::TxData(uint8_t Motor, float data)
{
    uint8_t mode;

    /* 根据选择的模式控制电机 */
    if (ui->List_Mode->currentText().compare("电流控制",Qt::CaseInsensitive) == 0) {
        mode = M_CtrlCurrent;
        this->setIq = data;
    } else if (ui->List_Mode->currentText().compare("速度控制",Qt::CaseInsensitive) == 0) {
        mode = M_CtrlSpeed;
        this->setSpeed = data;
    } else if (ui->List_Mode->currentText().compare("接近式速度控制",Qt::CaseInsensitive) == 0) {
        mode = M_CtrlTraSpeed;
        this->setSpeed = data;
    } else if (ui->List_Mode->currentText().compare("角度控制",Qt::CaseInsensitive) == 0) {
        mode = M_CtrlAngle;
        this->setAngle = data;
    } else {
        this->CtrDebug("#B71C1C", "错误 》》 选择了错误的控制模式 ×");
        return ;
    }

    if (uartComm.tx_MotorCtrl(Motor, mode, data) == Comm_OK) {
        this->CtrDebug("#1E88E5", "发送成功 √","#512DA8", "Mode:" + ui->List_Mode->currentText().mid(0,4) + " " + "Value:" + QString::number(double(data), 'g', 4));
    } else {
        this->CtrDebug("#D81B60", "发送失败 ×");
    }
}

void control::on_Bt_CtrlStraight_clicked()
{
    float _txData;

    if (this->GetCtrlData(_txData) == 0) {
        return;
    }

    this->TxData(M0, _txData);
}

void control::on_Bt_CtrlBack_clicked()
{
    float _txData;

    if (this->GetCtrlData(_txData) == 0) {
        return;
    }

    this->TxData(M0, -_txData);
}

void control::on_Bt_Ctrl0_clicked()
{
    this->TxData(M0, 0);
}

void control::onRadioClickSlot()
{
    switch(pbuttonGroup->checkedId())
    {
    case 0:
        MotorDataNum = 1;
        this->CtrDebug("#E65100", "你选择了使用了第一组数据");
        break;
    case 1:
        MotorDataNum = 2;
        this->CtrDebug("#E65100", "你选择了使用了第二组数据");
        break;
    case 2:
        MotorDataNum = 3;
        this->CtrDebug("#E65100", "你选择了使用了第三组数据");
        break;
    }
}

void control::on_Bt_setWaveFormMax_clicked()
{
    qDebug()<<"确实点击了清除曲线";
    this->WaveFormMax = ui->input_DataMax->text().toInt();
    this->CtrDebug("#1976D2","曲线最大容量设置成功 √");
}

void control::on_Slider_3_sliderMoved(int position)
{
    float ctrlData;
    float max = ui->data_ctrl2Max->text().toFloat();
    float min = ui->data_ctrl2Min->text().toFloat();
    float mid = (max + min) / 2.0f;

    if (position > 0) {
        ctrlData = (max - mid) * ((position) / 200.f);
    } else {
        ctrlData = (min - mid) * ((-position) / 200.f);
    }
    ctrlData = ctrlData + mid;

    ui->data_ctrl3->setText(QString::number(double(ctrlData)));

    if (ui->EN_Always->isChecked() == true) {
        this->TxData(M0, ctrlData);
    }
}

void control::on_Slider_3_sliderPressed()
{
    if (pbuttonGroup->checkedId() != 2) {
        this->ui->radio_CtrlData3->setChecked(1);
        this->onRadioClickSlot();
    }
}

void control::on_Bt_ClearAll_clicked()
{
    lsAngle->clear();
    lsSpeed->clear();
    lsIq->clear();
    this->CtrDebug("#2E7D32","清除成功 √");
}
